package com.linkq.ipinyin.schedule;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.linkq.ipinyin.mapper.*;
import com.linkq.ipinyin.model.*;
import com.linkq.ipinyin.utils.DateUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @FileName StudyPlanSchedule
 * @Description
 * @Author wangpeng
 * @date 2025-01-01
 **/

@Component
public class StudyPlanSchedule {
    @Autowired
    private StudyPlanMapper studyPlanMapper;

    @Autowired
    private ExecutionPlanMapper executionPlanMapper;

    @Autowired
    private PopQuizMapper popQuizMapper;

    @Autowired
    private TextMapper textMapper;

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private CnCharacterMapper characterMapper;

    @Autowired
    private ExecutionContentMapper executionContentMapper;

    // @Scheduled(fixedRate = 10 * 1000)
    public void createExecutionPlan() {
        // 查询尚未创建执行计划的学习计划
        List<StudyPlan> studyPlans = studyPlanMapper.selectList(
                Wrappers.<StudyPlan>lambdaQuery()
                        .eq(StudyPlan::getIsCreateExecution, 0)
        );
        if (CollectionUtils.isNotEmpty(studyPlans)) {
            studyPlans.forEach(x -> {
                // 计算共有多少天
                Date beginTime = x.getStartTime();
                Date endTime = x.getEndTime();
                long days = ChronoUnit.DAYS.between(beginTime.toInstant(), endTime.toInstant());
                // 计算有多少课文
                List<String> unitList = new ArrayList<>();
                if (StringUtils.isNotBlank(x.getUnit())) {
                    unitList = Arrays.asList(x.getUnit().split(","));
                }
                List<Text> texts = textMapper.selectList(
                        Wrappers.<Text>lambdaQuery()
                                .eq(Text::getGrade, x.getGrade())
                                .in(CollectionUtils.isNotEmpty(unitList), Text::getUnit, unitList)
                );
                int textCount = texts.size();
                int textPerDay = (int) (textCount / days);
                int questionNumber = x.getQuestionNumber();
                for (int i = 0; i < days; i++) {
                    ExecutionPlan executionPlan = new ExecutionPlan();
                    executionPlan.setPlanId(x.getId());
                    executionPlan.setPlanStartTime(DateUtils.dateCaculate(x.getStartTime(), i, Calendar.DAY_OF_MONTH));
                    executionPlan.setPlanEndTime(DateUtils.dateCaculate(executionPlan.getPlanStartTime(), 1, Calendar.DAY_OF_MONTH));
                    // executionPlan.setCorrectStartTime(executionPlan.getPlanStartTime());
                    // executionPlan.setCorrectEndTime(executionPlan.getExecuteEndTime());
                    executionPlan.setSort(i);
                    int beginText = textPerDay * i;
                    int endText = Math.min(beginText + textPerDay, textCount);
                    List<Integer> textIds = texts.subList(beginText, endText).stream().map(Text::getId).collect(Collectors.toList());
                    executionPlan.setStudyContent(StringUtils.join(textIds, ","));
                    executionPlanMapper.insert(executionPlan);
                    int executionPlanId = executionPlan.getId();
                    // 查询上一次执行计划的错题
//                    if (i > 0) {
//                        List<BcPopQuiz> lastWrongQuestion = popQuizMapper.selectList(
//                                Wrappers.<BcPopQuiz>lambdaQuery()
//                                        .eq(BcPopQuiz::getExecutionId, i - 1)
//                                        .eq(BcPopQuiz::getIsCorrect, 2)
//                        );
//                        if (CollectionUtils.isNotEmpty(lastWrongQuestion)) {
//                            for (BcPopQuiz pq : lastWrongQuestion) {
//                                BcPopQuiz popQuiz = new BcPopQuiz();
//                                popQuiz.setQuestionExecutionId(i - 1);
//                                popQuiz.setQuestionId(pq.getQuestionId());
//                                popQuiz.setExecutionId(executionPlanId);
//                                popQuiz.setQuestionType(2);
//                                popQuizMapper.insert(popQuiz);
//                            }
//                        }
//                    }
                    List<Question> questions = questionMapper.selectList(
                            Wrappers.<Question>lambdaQuery()
                                    .in(Question::getText, textIds)
                    );
                    List<Question> popQuizQuestion = allocateQuestion(questions,textIds, questionNumber);

                    popQuizQuestion.forEach(pq -> {
                        PopQuiz popQuiz = new PopQuiz();
                        popQuiz.setExecutionId(executionPlanId);
                        popQuiz.setQuestionId(pq.getId());
                        popQuiz.setQuestionType(1);
                        popQuizMapper.insert(popQuiz);
                    });
                }
                x.setIsCreateExecution(1);
                studyPlanMapper.updateById(x);
            });
        }
    }

    private List<Question> allocateQuestion(List<Question> questions, List<Integer> textIds, int questionNumber) {
        List<Question> result = new ArrayList<>();
        for (int textId : textIds){
            List<Question> qs = questions.stream().filter(x -> x.getText() == textId).collect(Collectors.toList());
            if (questionNumber >= qs.size()) {
                result.addAll(qs);
            } else {
                List<Question> copyList = new ArrayList<>(qs);
                Collections.shuffle(copyList);
                result.addAll(copyList.subList(0, questionNumber));
            }
        }
        return result;
    }

    @Scheduled(fixedRate = 10 * 1000)
    public void createExecutionPlan1() {
        // 查询尚未创建执行计划的学习计划
        List<StudyPlan> studyPlans = studyPlanMapper.selectList(
                Wrappers.<StudyPlan>lambdaQuery()
                        .eq(StudyPlan::getIsCreateExecution, 0)
        );
        if (CollectionUtils.isNotEmpty(studyPlans)) {
            studyPlans.forEach(x -> {
                // 计算共有多少天
                Date beginTime = x.getStartTime();
                Date endTime = DateUtils.dateCaculate(x.getEndTime(), 1, Calendar.DAY_OF_MONTH);
                long days = ChronoUnit.DAYS.between(beginTime.toInstant(), endTime.toInstant());
                // 计算有多少汉字
                List<String> unitList = new ArrayList<>();
                if (StringUtils.isNotBlank(x.getUnit())) {
                    unitList = Arrays.asList(x.getUnit().split(","));
                }
                List<Text> texts = textMapper.selectList(
                        Wrappers.<Text>lambdaQuery()
                                .eq(Text::getGrade, x.getGrade())
                                .in(CollectionUtils.isNotEmpty(unitList), Text::getUnit, unitList)
                );
                if (CollectionUtils.isEmpty(texts)) {
                    x.setIsCreateExecution(2);
                    return;
                }
                List<CnCharacter> characterList = characterMapper.selectList(
                        Wrappers.<CnCharacter>lambdaQuery()
                                .in(CnCharacter::getBelongText, texts.stream().map(Text::getId).collect(Collectors.toList()))
                                .eq(null != x.getCharacterType(), CnCharacter::getCharacterType, x.getCharacterType())
                );
                if (CollectionUtils.isEmpty(characterList)) {
                    x.setIsCreateExecution(3);
                    return;
                }
                characterList.sort(Comparator.comparingInt(CnCharacter::getBelongText));
                int characterCount = characterList.size();
                int textPerDay = characterCount < days ? 1 : (int) (characterCount / days);
                boolean finishFlag = false;
                for (int i = 0; i < days; i++) {
                    ExecutionPlan executionPlan = new ExecutionPlan();
                    executionPlan.setPlanId(x.getId());
                    executionPlan.setPlanStartTime(DateUtils.dateCaculate(x.getStartTime(), i, Calendar.DAY_OF_MONTH));
                    executionPlan.setPlanEndTime(DateUtils.dateCaculate(executionPlan.getPlanStartTime(), 1, Calendar.DAY_OF_MONTH));
                    executionPlan.setSort(i);
                    executionPlan.setStatus(0);
                    int beginCharacter = textPerDay * i;
                    int endCharacter = beginCharacter + textPerDay;
                    if (endCharacter >= characterCount) {
                        endCharacter = characterCount;
                        finishFlag = true;
                    }
                    List<Integer> characterIds = characterList.subList(beginCharacter, endCharacter).stream().map(CnCharacter::getId).collect(Collectors.toList());
                    executionPlanMapper.insert(executionPlan);
                    int executionPlanId = executionPlan.getId();
                    characterIds.forEach(ch -> {
                        ExecutionContent executionContent = new ExecutionContent();
                        executionContent.setExecutionPlanId(executionPlanId);
                        executionContent.setCharacterId(ch);
                        executionContent.setQuestionType(1);
                        executionContent.setIsCorrect(3);
                        executionContentMapper.insert(executionContent);
                    });
                    if (finishFlag) {
                        break;
                    }
                }
                x.setIsCreateExecution(1);
                studyPlanMapper.updateById(x);
            });
        }
    }
}
